// excerpts from http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#include "Channel.h"
#include "EventLoop.h"

#include "logging/Logging.h"

#include <poll.h>

using namespace learnmuduo;

const int Channel::kNoneEvent = 0;
const int Channel::kReadEvent = POLLIN | POLLPRI;
const int Channel::kWriteEvent = POLLOUT;

Channel::Channel(EventLoop *loop, int fdArg)
    : loop_(loop), fd_(fdArg), events_(0), revents_(0), index_(-1) {}

// 会调用 `EventLoop::updateChannel()`，后者会转而调用 `Poller::updateChannel()`
void Channel::update() { loop_->updateChannel(this); }

// 是 `Channel` 的核心，它由 `EventLoop::loop()` 调用，它的功能是根据 `revents_` 的值分别调用不同的用户回调。这个函数以后还会扩充。
void Channel::handleEvent() {
  if (revents_ & POLLNVAL) { // POLLNVAL表示fd非法，记录警告日志
    LOG_WARN << "Channel::handle_event() POLLNVAL";
  }

  if (revents_ & (POLLERR | POLLNVAL)) { // 发生错误事件时调用错误回调
    if (errorCallback_)
      errorCallback_();
  }
  if (revents_ & (POLLIN | POLLPRI | POLLRDHUP)) { // 发生读相关事件时调用读回调
    if (readCallback_)
      readCallback_();
  }
  if (revents_ & POLLOUT) { // 发生写事件时调用写回调
    if (writeCallback_)
      writeCallback_();
  }
}
